05 优化程序性能

优化程序性能

程序的目标:

  1. 清晰简洁
  2. 高性能

高性能的手段:

  1. 适当的算法和数据结构
  2. 编写易让编译器优化的代码
  3. 多线程

本章的核心是:

  1. 编写易让编译器优化的代码
  2. 结合处理器来优化代码的执行

优化编译器的能力和局限性

哪些编码方式是编译器不好优化的?

  1. 内存别名使用:编译器无法判断不同的指针是否会指向内存的同一个位置

代码案例:

1
2
3
4
5
6
7
void twiddle1(long *xp, long *yp){
*xp += *yp;
*xp += *yp;
}
void twiddle2(long *xp, long *yp){
*xp += 2 * *yp;
}

  1. 函数调用:编译器无法判断函数是否存在副作用,如修改了全局变量

代码案例:

1
2
3
4
5
6
7
long func();
long func1(){
return f() + f() + f() + f();
}
long func2(){
return 4*f();
}

表示程序性能

如何衡量程序的性能?什么是每元素的周期数(CPE)

使用每元素的周期数(CPE)衡量,“元素”理解为需要被处理的数据量。
每元素的周期数(CPE)理解为处理元素所需的时钟周期

每元素的周期数(CPE)

上图中的斜率就是每元素的周期数(CPE)

什么是最小二乘拟合,有什么用?

最小二乘拟合

程序示例

示例代码:合并运算

合并运算

优化级别对性能的影响

优化级别

消除循环的低效率

循环中的低效代码?如何优化?

对上述的示例代码
循环中反复调用了一个结果不变得函数

改进:

消除循环的低效率

编译器为何不自动优化?

函数调用的副作用影响

消除不必要的寄存器消耗

哪些代码会造成不必要的寄存器消耗?如何优化?

上述案例代码中

1
*dest = *dest OP val

*dest的结果没有任何作用

但是却造成了寄存器的额外消耗

改进:

消除不必要的寄存器消耗

编译器为何不自动优化?

内存别名使用的影响

理解现代处理器

剩下的章节内容:

  1. 了解现代处理器的乱序执行
  2. 利用乱序、并行提高程序性能

本文标题:05 优化程序性能

文章作者:Sun

发布时间:2019年05月14日 - 16:05

最后更新:2019年09月11日 - 17:09

原始链接:https://sunyi720.github.io/2019/05/14/系统原理/05 优化程序性能/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。